/* Copyright (C) Abu Rizal, 2009.
 * 
 * This file is part of QurText.
 * 
 * QurText is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * QurText is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with QurText. If not, see <http://www.gnu.org/licenses/>.
 */
package qurtext.client;

import java.util.ArrayList;
import java.util.TreeMap;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.MouseOutEvent;
import com.google.gwt.event.dom.client.MouseOutHandler;
import com.google.gwt.event.dom.client.MouseOverEvent;
import com.google.gwt.event.dom.client.MouseOverHandler;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DeferredCommand;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DeckPanel;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.StackPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

public class NavigationView extends BaseView {
	private final Button initButton=new Button("Initialize List");
	private final Button initAllButton=new Button("Initialize All Sections");
	private NavigationPresenter navigationPresenter;
	private final HorizontalPanel chapterAdminBar = new HorizontalPanel();
	private final Button initAllLiteralButton=new Button("Initialize All Literals");
	private final Label initText=new Label("Click on a button!");
	private final VerticalPanel chapterPanel = new VerticalPanel();
	private final FlowPanel chapterFlow = new FlowPanel();
	private final VerticalPanel juzPanel = new VerticalPanel();
	private final StackPanel listTabPanel = new StackPanel();
	private MainPresenter mainPresenter;
	private DeckPanel juzDeck = new DeckPanel();
	private HorizontalPanel juzTopPanel = new HorizontalPanel();
	private TreeMap<String,HTML> juzBottomMap = new TreeMap<String,HTML>();
	private TreeMap<String,HTML> juzBottomTopMap = new TreeMap<String,HTML>();
	private TreeMap<Integer,HTML> juzTopBottomMap = new TreeMap<Integer,HTML>();
	private HTML currentJuzBottomHtml;
	private MouseOverHandler juzTopMouseOver = new MouseOverHandler() {

		@Override
		public void onMouseOver(MouseOverEvent event) {
			if (null!=currentJuzTopHtml) currentJuzTopHtml.setHTML("&nbsp;");
			currentJuzTopHtml = (HTML) event.getSource();
			int juzNo = Integer.valueOf(currentJuzTopHtml.getElement().getAttribute("name"));

			if (null!=currentJuzBottomHtml) {
				currentJuzBottomHtml.setHTML("&nbsp;");
				currentJuzBottomHtml.setHeight("");
			}
			currentJuzBottomHtml = juzTopBottomMap.get(juzNo);
			String token = currentJuzBottomHtml.getElement().getAttribute("name");
			currentJuzBottomHtml.setHTML(token);

			currentJuzTopHtml.setHTML("<a href='#" + token + "'>Juz " + juzNo + "</a>");
			juzDeck.showWidget(juzNo-1);
		}
		
	};
	private Command showCurrentJuzCommand = new Command(){

		@Override
		public void execute() {
			if (null==currentJuzTopHtml)
			showCurrentJuz();
		}
		
	};
	private MouseOutHandler juzTopMouseOut = new MouseOutHandler() {

		@Override
		public void onMouseOut(MouseOutEvent event) {
			currentJuzTopHtml=null;
			HTML source = (HTML) event.getSource();
			source.setHTML("&nbsp;");

			if (null!=currentJuzBottomHtml) {
				currentJuzBottomHtml.setHTML("&nbsp;");
				currentJuzBottomHtml.setHeight("");
			}
			DeferredCommand.addCommand(showCurrentJuzCommand);
		}
		
	};
	
	private HTML currentJuzTopHtml;
	
	private MouseOverHandler juzBottomMouseOver = new MouseOverHandler() {

		@Override
		public void onMouseOver(MouseOverEvent event) {
			if (null!=currentJuzBottomHtml) {
				currentJuzBottomHtml.setHTML("&nbsp;");
				currentJuzBottomHtml.setHeight("");
			}
			currentJuzBottomHtml = (HTML) event.getSource();
			String token = currentJuzBottomHtml.getElement().getAttribute("name");
			currentJuzBottomHtml.setHTML("<a href='#" + token + "'>" + token + "</a>");
			currentJuzTopHtml = juzBottomTopMap.get(token);
			Integer juzNo = Integer.valueOf(currentJuzTopHtml.getElement().getAttribute("name"));
			currentJuzTopHtml.setHTML("Juz " + juzNo);
			currentJuzBottomHtml.setHeight("40");
		}
		
	};
	private MouseOutHandler juzBottomMouseOut = new MouseOutHandler() {

		@Override
		public void onMouseOut(MouseOutEvent event) {
			if (null!=currentJuzTopHtml) currentJuzTopHtml.setHTML("&nbsp;");
			currentJuzTopHtml=null;
			HTML source = (HTML) event.getSource();
			source.setHTML("&nbsp;");
			source.setHeight("");
			DeferredCommand.addCommand(showCurrentJuzCommand);
		}
		
	};

	public MainPresenter getMainPresenter() {
		return mainPresenter;
	}

	public void setMainPresenter(MainPresenter mainPresenter) {
		this.mainPresenter = mainPresenter;
	}

	private ClickHandler updateClickHandler = new ClickHandler() {

		@Override
		public void onClick(ClickEvent event) {
			Widget sender=(Widget) event.getSource();
			String historyToken = sender.getElement().getAttribute("name");
			mainPresenter.handleHistoryToken(historyToken);
		}

	};

	private ClickHandler juzTopHtmlClick = new ClickHandler() {

		@Override
		public void onClick(ClickEvent event) {
			HTML source = (HTML) event.getSource();
			int juzNo = Integer.valueOf(source.getElement().getAttribute("name"));

			HTML juzBottomHTML = juzTopBottomMap.get(juzNo);
			String token = juzBottomHTML.getElement().getAttribute("name");
			mainPresenter.handleHistoryToken(token);
		}
		
	};

	public void onNavigationViewLoad() {
		initButton.addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				navigationPresenter.initSectionList();
			}

		});

		initAllButton.addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				initAllButton.setEnabled(false);
				navigationPresenter.initAllSections();
			}

		});

		initAllLiteralButton.addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				navigationPresenter.initAllLiterals();
			}
			
		});

		chapterAdminBar.setVisible(false);
	    chapterAdminBar.add(initButton);
	    chapterAdminBar.add(initAllButton);
	    chapterAdminBar.add(spacer());
	    chapterAdminBar.add(initAllLiteralButton);
	    chapterAdminBar.add(spacer());
	    chapterAdminBar.add(initText);
	    
	    chapterPanel.setWidth("100%");
	    chapterPanel.add(chapterAdminBar);
	    chapterPanel.add(chapterFlow);
	    HTML footer = new HTML(QurText.FOOTER);
	    footer.addStyleName("footer");
	    chapterPanel.add(footer);

	    juzPanel.setWidth("100%");
	    listTabPanel.add(chapterPanel,"Chapter List");
	    
	    mainPresenter.getMainView().addProgressPanel(juzPanel,"Juz List");
	    listTabPanel.showStack(0);
	}

	public void setNavigationPresenter(NavigationPresenter navigationPresenter) {
		this.navigationPresenter = navigationPresenter;
	}

	public NavigationPresenter getNavigationPresenter() {
		return navigationPresenter;
	}

	public void setStatusText(String statusText) {
		initText.setText(statusText);
	}

	public void showAdminTab() {
		chapterAdminBar.setVisible(true);
	}

	public void showChapterList(TreeMap<Integer, ClientChapter> chapterMap) {
		chapterFlow.clear();
		for (ClientChapter chapter: chapterMap.values()) {
			Hyperlink hyperlink = new Hyperlink("" + chapter.chapterNo, "" + chapter.chapterNo + ":1");
	    	hyperlink.addClickHandler(updateClickHandler );
	    	hyperlink.getElement().getStyle().setProperty("display", "inline");
	    	chapterFlow.add(hyperlink);
	    	chapterFlow.add(spacer());
			hyperlink.setTitle(chapter.transliteration);
	    }
	
	}

	public void setInitAllLiteralButtonEnabled(boolean enabled) {
		initAllLiteralButton.setEnabled(enabled);
	}

	public void setInitButtonEnabled(boolean enabled) {
		initButton.setEnabled(enabled);
	}

	public void showJuzList(ArrayList<ClientJuz> juzList) {
		juzPanel.clear();
		juzTopPanel.setWidth("100%");
		juzTopPanel.setHeight("100%");
		juzDeck.setWidth("100%");
		juzPanel.add(juzTopPanel);
		juzPanel.add(juzDeck);
		HTML juzTopHtml=null;
		HorizontalPanel juzBottomPanel=null;
		for (ClientJuz juz:juzList) {
			juzTopHtml=new HTML("&nbsp;");
			juzTopHtml.addStyleName("juzbox");
			juzTopHtml.addClickHandler(juzTopHtmlClick);
			juzTopHtml.addMouseOverHandler(juzTopMouseOver);
			juzTopHtml.addMouseOutHandler(juzTopMouseOut);
			juzTopHtml.getElement().setAttribute("name",""+juz.juzNo);
			juzTopPanel.add(juzTopHtml);

			juzBottomPanel = new HorizontalPanel();
			juzBottomPanel.setWidth("100%");
			juzBottomPanel.setHeight("100%");
			juzDeck.add(juzBottomPanel);
			boolean firstToken=true;
			for (String token:juz.tokens) {
				HTML juzBottomHTML = showJuzBottomLink(juzBottomPanel, token);
				if (firstToken) {
					firstToken=false;
					juzTopBottomMap.put(juz.juzNo,juzBottomHTML);
					ClientSection section = mainPresenter.getAllSections().get(navigationPresenter.getSectionNo(token));
					String sectionToken = "" + section.chapter + ":" + section.verse;
					if ( ! token.equals(sectionToken)) {
						juzBottomTopMap.put(sectionToken,juzTopHtml);
						juzBottomMap.put(sectionToken,juzBottomHTML);
					}
				}
				juzBottomTopMap.put(token,juzTopHtml);
				juzBottomMap.put(token,juzBottomHTML);
			}
		}
		juzDeck.showWidget(0);
	}

	private HTML showJuzBottomLink(HorizontalPanel juzBottmPanel, String token) {
		HTML sectionHyperlink = new HTML("&nbsp;");
		sectionHyperlink.addStyleName("juzbox");
		sectionHyperlink.addClickHandler(updateClickHandler );
		sectionHyperlink.addMouseOverHandler(juzBottomMouseOver);
		sectionHyperlink.addMouseOutHandler(juzBottomMouseOut);
		sectionHyperlink.getElement().setAttribute("name", token);
		juzBottmPanel.add(sectionHyperlink);
		return sectionHyperlink;
	}

	public Widget getPanel() {
		return listTabPanel;
	}

	public void showUserProgress() {
		ClientUser user = mainPresenter.getUserPresenter().getCurrentUser();
			for (HTML juzBottomLeftMostHTML:juzTopBottomMap.values()) {
			HTML juzTopHtml=juzBottomTopMap.get(juzBottomLeftMostHTML.getElement().getAttribute("name"));
			boolean juzCompleted = true;
			HorizontalPanel juzBottomPanel = (HorizontalPanel)juzBottomLeftMostHTML.getParent();
			for (int i=0;i<juzBottomPanel.getWidgetCount();i++) {
				HTML juzBottomHtml = (HTML) juzBottomPanel.getWidget(i);
				String token=juzBottomHtml.getElement().getAttribute("name");
				if (user.sectionRead[navigationPresenter.getSectionNo(token)]) {
					juzBottomHtml.addStyleName("completed");
				} else {
					juzBottomHtml.removeStyleName("completed");
					juzCompleted = false;
				}
			}
			if (juzCompleted) {
				juzTopHtml.addStyleName("completed");
			} else {
				juzTopHtml.removeStyleName("completed");
			}
		}
	}

	public void showCurrentJuz() {
		ClientSection section = mainPresenter.getCurrentSection();
		if (null==section) return;
		String token="" + section.chapter + ":" + section.verse;
		currentJuzBottomHtml = juzBottomMap.get(token);
		token=currentJuzBottomHtml.getElement().getAttribute("name");
		currentJuzTopHtml = juzBottomTopMap.get(token);
		Integer juzNo = Integer.valueOf(currentJuzTopHtml.getElement().getAttribute("name"));
		juzDeck.showWidget(juzNo-1);

		for (int i=0;i<juzTopPanel.getWidgetCount();i++) {
			HTML topHTML = (HTML) juzTopPanel.getWidget(i);
			topHTML.setHTML("&nbsp;");
		}
		HorizontalPanel juzBottomPanel = (HorizontalPanel) currentJuzBottomHtml.getParent(); 
		for (int i=0;i<juzBottomPanel.getWidgetCount();i++) {
			HTML bottomHTML = (HTML) juzBottomPanel.getWidget(i);
			bottomHTML.setHTML("&nbsp;");
		}
		currentJuzBottomHtml.setHTML(token);
		currentJuzTopHtml.setHTML("Juz " + juzNo);
	}

}
